		TITLE	ALLOCATE - Copyright (c) SLR Systems 1990

		INCLUDE MACROS
		INCLUDE SECTS

if	any_overlays

		PUBLIC	ALLOCATE_ALLOCATABLES

		.DATA

	SOFT	EXTW	LIBALLOC_STUFF,PUBALLOC_STUFF,ALLO_LAST_BLOCK

	SOFT	EXTD	FIRST_MODULE

		.CODE	MIDDLE_TEXT

	SOFT	EXTP	RETURN_LOWEST_SECTION,INSTALL_LIBALLOC,GET_NEW_LOG_BLK,ALLO_POOL_GET,RELEASE_MINIDATA,RELEASE_BLOCK
	SOFT	EXTP	SAY_VERBOSE

		ASSUME	DS:NOTHING

ALLOCATE_ALLOCATABLES	PROC
		;
		;DO SEGMOD ALLOCATION FOR ALLOCATABLE SEGMODS
		;
		MOV	AX,SEG ALLOCATING_MSG
		MOV	SI,OFF ALLOCATING_MSG
		CALL	SAY_VERBOSE
		BITT	ANY_ALLOCATABLE
		JZ	0$
		;
		;FIRST, SCAN MODULES FOR ALLOCATABLES, AND UPDATE SEGMODS
		;BASED ON PUBLICS...
		;
		CALL	SCAN_MODULES
		;
		;NEXT, PROCESS PUBALLOC RECORDS INTO LIBALLOC SPACE...
		;THIS WAY WE CAN JUST RE-PROCESS LIBALLOC STUFF AS NEEDED...
		;
		MOV	AX,PUBALLOC_STUFF.ALLO_FIRST_ITEM.SEGM
		OR	AX,LIBALLOC_STUFF.ALLO_FIRST_ITEM.SEGM
		JZ	0$
		LDS	SI,PUBALLOC_STUFF.ALLO_FIRST_ITEM
		JMP	4$

0$:
		JMP	90$

1$:
		SYM_CONV_DS
		PUSHM	[SI]._PUBALLOC_NEXT.OFFS,[SI]._PUBALLOC_NEXT.SEGM
		;
		;_FROM IS REFERENCING SEGMOD, _TO IS REFERENCED SYMBOL
		;
		PUSHM	[SI]._PUBALLOC_FROM.OFFS,[SI]._PUBALLOC_FROM.SEGM
		;
		;IF SYMBOL IS NOT A NORMAL RELOCATABLE SYMBOL, IGNORE
		;
		LDS	SI,[SI]._PUBALLOC_TO
		SYM_CONV_DS
		MOV	AL,[SI]._S_NSYM_TYPE
		CMP	AL,NSYM_LOC_RELOCATABLE
		JZ	2$
		CMP	AL,NSYM_RELOCATABLE
		JNZ	38$
2$:
		;
		;IF SYMBOL'S SEGMOD IS SECTION_ASSIGNED OR LEVEL_0, IGNORE
		;
		LES	DI,_S_FRAME[SI]
		MOV	CX,ES
		SYM_CONV_ES
		TEST	ES:[DI]._SM_PLTYPE,MASK SECTION_ASSIGNED+MASK LEVEL_0_SECTION
		JNZ	38$
		;
		;MAKE SURE SYMBOL'S SEGMOD REFLECTS LOWEST SYMBOL REFERENCE
		;
		PUSHM	CX,DI
		LEA	DI,[DI]._SM_SECTION
		LEA	SI,[SI]._S_SECTION
		CALL	RETURN_LOWEST_SECTION
		POPM	SI,CX
		MOV	DS,CX
		SYM_CONV_DS
		CMP	[SI]._SM_SECTION.OFFS,BX
		JZ	35$		;PROBABLY A MATCH
		MOV	[SI]._SM_SECTION.OFFS,BX
36$:
		MOV	[SI]._SM_SECTION.SEGM,DX
		MOV	ES,DX
		SYM_CONV_ES
		CMP	ES:[BX]._SECT_LEVEL,0
		JNZ	37$
		OR	[SI]._SM_PLTYPE,MASK LEVEL_0_SECTION
		;
		;YOU ARE DONE IF ALREADY LEVEL_0_SECTION
		;
		JMP	38$

35$:
		CMP	[SI]._SM_SECTION.SEGM,DX
		JNZ	36$
37$:
		;
		;OK, REFERENCE THIS SEGMOD FROM THE OTHER...
		;
		POPM	AX,BX
		MOV	DX,CX
		MOV	CX,SI
		;
		;DX:CX IS TO
		;AX:BX IS FROM
		;
		CMP	CX,BX
		JZ	375$
374$:
		CALL	INSTALL_LIBALLOC
		JMP	39$

38$:
		ADD	SP,4
39$:
		POPM	DS,SI
4$:
		MOV	AX,DS
		OR	AX,AX
		JZ	5$
		JMP	1$

375$:
		CMP	AX,DX
		JNZ	374$
		JMP	39$

		;
		;OK, NOW WE START REPROCESSING TILL NOTHING CHANGES
		;
		ASSUME	DS:NOTHING
5$:
		RESS	SEGMOD_MOVED		;NOTHING CHANGED
		;
		;CLEAR POINTERS TO LIBALLOC STUFF
		;
		CALL	GET_NEW_LOG_BLK
		FIXES
		LEA	DI,LIBALLOC_STUFF.ALLO_FIRST
		STOSW
		XCHG	AX,BX
		MOV	AX,PAGE_SIZE-16 	;BYTES LEFT THIS BLOCK
		STOSW
		MOV	AX,16
		STOSW				;NEXT POINTER
		MOV	AX,BX
		STOSW
		XOR	AX,AX			;NB_PTR
		STOSW
		XCHG	AX,BX
		STOSW
		MOV	WPTR ES:[DI],8		;NB_COUNT
		MOV	ES,AX
		CONV_ES
		XOR	DI,DI
		MOV	CX,8
		XOR	AX,AX
		REP	STOSW
		LDS	SI,LIBALLOC_STUFF.ALLO_FIRST_ITEM
		MOV	LIBALLOC_STUFF.ALLO_FIRST_ITEM.SEGM,AX
		MOV	ALLO_LAST_BLOCK,DS
		JMP	8$

51$:
		SYM_CONV_DS
		PUSHM	[SI]._LIBALLOC_NEXT.OFFS,[SI]._LIBALLOC_NEXT.SEGM
		LES	DI,[SI]._LIBALLOC_FROM
		LDS	SI,[SI]._LIBALLOC_TO
		MOV	CX,DS
		SYM_CONV_DS
		;
		;SKIP IF TARGET SM ALREADY HAS BEEN LEVEL_0_ED
		;
		TEST	[SI]._SM_PLTYPE,MASK LEVEL_0_SECTION+MASK SECTION_ASSIGNED
		JNZ	59$
		PUSHM	ES,DI,CX,SI
		SYM_CONV_ES
		LEA	SI,[SI]._SM_SECTION
		LEA	DI,[DI]._SM_SECTION
		CALL	RETURN_LOWEST_SECTION
		POPM	SI,CX,DI,ES
		MOV	DS,CX
		SYM_CONV_DS
		CMP	[SI]._SM_SECTION.OFFS,BX
		JZ	55$
		MOV	[SI]._SM_SECTION.OFFS,BX
52$:
		SETT	SEGMOD_MOVED
		MOV	[SI]._SM_SECTION.SEGM,DX
		;
		;SEE IF NOW LEVEL_0
		;
		MOV	DX,ES
		SYM_CONV_ES
		TEST	ES:[DI]._SM_PLTYPE,MASK LEVEL_0_SECTION
		JZ	56$			;NOPE, GO STORE THIS
		OR	[SI]._SM_PLTYPE,MASK LEVEL_0_SECTION
		JMP	59$

55$:
		CMP	[SI]._SM_SECTION.SEGM,DX
		JNZ	52$
		MOV	DX,ES
		;
		;SECTION DIDN'T CHANGE, JUST STORE THIS GUY
		;
56$:
		;
		;CX:SI	IS _TO
		;DX:DI	IS _FROM
		;
		PUSHM	DI,SI
		LEA	SI,LIBALLOC_STUFF
		MOV	AX,(SIZE LIBALLOC_STRUCT+1) AND 0FFFEH
		CALL	ALLO_POOL_GET
		PUSHM	AX,DI
		XOR	AX,AX
		STOSW			;NEXT_HASH
		STOSW
		POP	AX
		XCHG	AX,DGROUP:ALLO_FIRST_ITEM[SI].OFFS
		STOSW
		POP	AX
		XCHG	AX,DGROUP:ALLO_FIRST_ITEM[SI].SEGM
		STOSW
		;
		;FROM
		;
		POPM	SI,AX
		STOSW
		MOV	AX,DX
		STOSW
		;
		;TO
		;
		MOV	AX,SI
		STOSW
		MOV	AX,CX
		STOSW

59$:
		POPM	DS,SI
		;
		;RELEASE A BLOCK?
		;
		MOV	AX,DS
		CMP	ALLO_LAST_BLOCK,AX
		JZ	8$
		XCHG	ALLO_LAST_BLOCK,AX
		CALL	RELEASE_BLOCK
8$:
		MOV	AX,DS
		OR	AX,AX
.EN CJ
		JNZ	51$
.DS CJ
		BITT	SEGMOD_MOVED
		JZ	9$
		JMP	5$

9$:
		;
		;RELEASE MEMORY
		;
		LEA	DI,LIBALLOC_STUFF
		CALL	RELEASE_MINIDATA
90$:
		;
		;IF VERBOSE, REPORT WHICH SECTION THESE SEGMODS WERE ASSIGNED
		;
		RET

ALLOCATE_ALLOCATABLES	ENDP

		ASSUME	DS:NOTHING

SCAN_MODULES	PROC	NEAR
		;
		;UPDATE SEGMODS BASED ON PUBLICS...
		;
		LDS	SI,FIRST_MODULE
		JMP	81$

2$:
		SYM_CONV_DS
		PUSHM	[SI]._S_NEXT_SYM.OFFS,[SI]._S_NEXT_SYM.SEGM
		;
		;ONLY INTERESTED IN RELOC OR LOC_RELOC
		;
		MOV	AL,[SI]._S_NSYM_TYPE
		CMP	AL,NSYM_LOC_RELOCATABLE
		JZ	21$
		CMP	AL,NSYM_RELOCATABLE
		JNZ	7$
21$:
		;
		;SEE IF SEGMOD IS ALLOCATABLE
		;
		LES	DI,[SI]._S_FRAME
		MOV	DX,ES
		SYM_CONV_ES
		TEST	ES:[DI]._SM_PLTYPE,MASK SECTION_ASSIGNED+MASK LEVEL_0_SECTION
		JNZ	7$
		;
		;OK, SET SM SECTION TO LOWEST OF THE TWO
		;
		PUSHM	DI,DX

		LEA	SI,[SI]._S_SECTION
		LEA	DI,[DI]._SM_SECTION
		CALL	RETURN_LOWEST_SECTION
		POPM	DS,SI
		SYM_CONV_DS
		CMP	[SI]._SM_SECTION.OFFS,BX
		JZ	25$
		MOV	[SI]._SM_SECTION.OFFS,BX
22$:
		MOV	[SI]._SM_SECTION.SEGM,DX
		;
		;SEE IF FRESHLY LEVEL_0_SECTION...
		;
		MOV	ES,DX
		SYM_CONV_ES
		CMP	ES:[BX]._SECT_LEVEL,0
		JNZ	7$
		OR	[SI]._SM_PLTYPE,MASK LEVEL_0_SECTION
7$:
		POPM	DS,SI
71$:
		MOV	AX,DS
		OR	AX,AX
		JNZ	2$
8$:
		POPM	DS,SI
81$:
		MOV	CX,DS
		JCXZ	9$
1$:
		SYM_CONV_DS
		PUSHM	[SI]._M_NEXT_MOD.OFFS,[SI]._M_NEXT_MOD.SEGM
if	fg_plink
		CMP	[SI]._M_SECTION.SEGM,0	;SECTION ASSIGNED FOR THIS?
		JNZ	8$
endif
		LES	DI,[SI]._M_FILE_LIST
		SYM_CONV_ES
		TEST	ES:[DI].FILE_LIST_PLINK_FLAGS,MASK LIB_ALLOCATE
		JZ	8$
		;
		;ALLOCATABLE MODULE, SCAN MY PUBDEFS FOR UPDATES TO SEGMODS
		;
		LDS	SI,[SI]._M_FIRST_PUB
		JMP	71$

25$:
		CMP	[SI]._SM_SECTION.SEGM,DX
		JNZ	22$
		JMP	7$

9$:
		RET

SCAN_MODULES	ENDP

iff	data_in_codeseg

		.DATA

endif

ALLOCATING_MSG	DB	LENGTH ALLOCATING_MSG-1,'Allocating Segments to overlay structure'

endif
		END

